package edu.pku.sei.modeler.model.notation.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.w3c.dom.Element;

import edu.pku.sei.modeler.model.xml.XMLUtility;

import edu.pku.sei.gefcommon.descriptor.annotation.MethodProperty;
import edu.pku.sei.modeler.model.core.MetaModelElement;


public class ShapeNode extends MetaModelElement {
	// these are not a part of shape model
	private Rectangle bound = null;
	private ShapeNode parent = null;
	//end
	private List children;
	
	public ShapeNode(){
		bound = new Rectangle(0,0,50,50);
		initChildrenList();
	}
	
	protected void initChildrenList(){
		children = new ArrayList();
	}
	protected void addChild(Object child,String prop){
		if(children!=Collections.EMPTY_LIST){
			children.add(child);
			((ShapeNode)child).setParent(this);
			this.fireStructureChange(prop, child);
		}
	}
	protected void removeChild(Object child,String prop){
		if(children!=Collections.EMPTY_LIST){
			children.remove(child);
			this.fireStructureChange(prop, child);
		}
	}
	protected List getChildren(){
		return children;
	}
	
	@MethodProperty(id="SHAPE_LOCATION",catalog="Shape",name="Location", setter="setLocation")
	public Point getLocation(){
		return bound.getLocation();
	}
	public void setLocation(Point p){
		setLocation(p.x,p.y);
	}
	@MethodProperty(id="SHAPE_SIZE",catalog="Shape",name="Size", setter="setSize")
	public Dimension getSize(){
		return bound.getSize();
	}
	public void setSize(Dimension d){
		setSize(d.width,d.height);
	}
	public void setBound(Rectangle r){
		bound.setBounds(r);
		this.firePropertyChange(ShapeConstance.REFRESH_VIEW, null, bound);
	}
	public void setLocation(int x,int y){
		bound.setLocation(x, y);
		this.firePropertyChange(ShapeConstance.REFRESH_VIEW, null, bound);
	}
	public void setSize(int w,int h){
		bound.setSize(w, h);
		this.firePropertyChange(ShapeConstance.REFRESH_VIEW, null, bound);
	}
	public void setBound(int x,int y,int w,int h){
		bound.setLocation(x, y);
		bound.setSize(w, h);
		this.firePropertyChange(ShapeConstance.REFRESH_VIEW, null, bound);
	}
	
	public Rectangle getBound(){
		return bound;
	}
	public ShapeNode getParent() {
		return parent;
	}
	public void setParent(ShapeNode parent) {
		this.parent = parent;
	}
	
	//add by fengchao
	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeAttribute(root, NotationPackage.SHAPENODE_BOUND_X, bound.x);
		XMLUtility.xmlInstance.serializeAttribute(root, NotationPackage.SHAPENODE_BOUND_Y, bound.y);
		XMLUtility.xmlInstance.serializeAttribute(root, NotationPackage.SHAPENODE_BOUND_WIDTH, bound.width);
		XMLUtility.xmlInstance.serializeAttribute(root, NotationPackage.SHAPENODE_BOUND_HEIGHT, bound.height);
		XMLUtility.xmlInstance.serializeNodeNotContain(root, NotationPackage.SHAPENODE_PARENT, parent);
		XMLUtility.xmlInstance.serializeNodes(root, NotationPackage.SHAPENODE_CHILDREN, children);
	}
	
	public void deSerialize(Element root) {
		super.deSerialize(root);
		int x = XMLUtility.xmlInstance.deSerializeInt(root, NotationPackage.SHAPENODE_BOUND_X);
		int y = XMLUtility.xmlInstance.deSerializeInt(root, NotationPackage.SHAPENODE_BOUND_Y);
		int width = XMLUtility.xmlInstance.deSerializeInt(root, NotationPackage.SHAPENODE_BOUND_WIDTH);
		int height = XMLUtility.xmlInstance.deSerializeInt(root, NotationPackage.SHAPENODE_BOUND_HEIGHT);
		this.bound = new Rectangle(x,y,width,height);
		this.parent = (ShapeNode) XMLUtility.xmlInstance.deSerializeNodeNotContain(root, NotationPackage.SHAPENODE_PARENT, this); 
		this.children.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, NotationPackage.SHAPENODE_CHILDREN));
	}
	
	public void dynamicSet(String featureID, Object value) {
		if(featureID.equals(NotationPackage.SHAPENODE_PARENT)) {
			this.parent = (ShapeNode)value;
		}
		
		else {
			super.dynamicSet(featureID, value);
		}
	}
	//end add
}
